﻿using Engine.Graphics;
using Engine.Graphics.VertexStructures;
using SharpDX;
using SharpDX.Direct3D11;
using System.Collections.Generic;
using System.IO;

namespace Engine.FileFormats3D.C11Undercover
{
    public class RoadNet : StandardGraphicBuffers, IRenderableObject
    {
        #region Private Fields

        private Engine engine;
        private List<Node> nodes;
        private VertexBufferBinding vertexBufferBinding;

        #endregion Private Fields

        #region Public Constructors

        public RoadNet(Engine engine)
            : base(engine.Device)
        {
            this.engine = engine;
            this.nodes = new List<Node>();
            this.engine.Grafic.AddRenderableObjects(this, 10);
        }

        #endregion Public Constructors

        #region Public Methods

        public static RoadNet FromFile(Engine engine, string PathToFile)
        {
            if (File.Exists(PathToFile))
            {
                FileStream fs = new FileStream(PathToFile, FileMode.Open);
                BinaryReader br = new BinaryReader(fs);

                RoadNet roadNet = new RoadNet(engine);
                // overjumping the header
                br.BaseStream.Position += 48;

                for (int i = 0; i < 633; i++)
                {
                    roadNet.nodes.Add(Node.FromStream(br));
                }

                roadNet.UpdateBuffers();

                br.Close();
                fs.Close();
                return roadNet;
            }
            throw new FileNotFoundException("File not found: " + PathToFile);
        }

        public new void Dispose()
        {
            this.engine.Grafic.RemoveRenderableObject(this);
            base.Dispose();
        }

        public void Render(int renderStep)
        {
            this.engine.Grafic.ClearColor = new Color4()
            {
                Alpha = System.Drawing.Color.DarkBlue.A / 255.0f,
                Red = System.Drawing.Color.DarkBlue.R / 255.0f,
                Green = System.Drawing.Color.DarkBlue.G / 255.0f,
                Blue = System.Drawing.Color.DarkBlue.B / 255.0f,
            };

            DeviceContext deviceContext = this.engine.Device.ImmediateContext;

            this.engine.Grafic.ShaderManager.SetShader(this.engine.Grafic.ShaderManager.ColorShader);

            deviceContext.InputAssembler.SetVertexBuffers(0, this.vertexBufferBinding);
            deviceContext.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.PointList;

            deviceContext.Draw(this.nodes.Count, 0);
        }

        #endregion Public Methods

        #region Private Methods

        private void UpdateBuffers()
        {
            MyOwnVertex.PositionColor[] vertices = new MyOwnVertex.PositionColor[this.nodes.Count];

            for (int i = 0; i < vertices.Length; i++)
            {
                vertices[i] = new MyOwnVertex.PositionColor(new SharpDX.Vector3(nodes[i].x, nodes[i].y + 50, nodes[i].z), new Color4());
            }

            base.UpdateVertexBuffer(vertices);
            lock (this.engine.Device.ImmediateContext)
                this.vertexBufferBinding = new VertexBufferBinding(base.VertexBuffer, MyOwnVertex.PositionNormalTextured.SizeInBytes(), 0);
        }

        #endregion Private Methods

        #region Private Structs

        private struct Node
        {
            #region Public Fields

            public float x, y, z;

            #endregion Public Fields

            #region Public Methods

            public static Node FromStream(BinaryReader br)
            {
                Node node = new Node()
                {
                    x = br.ReadSingle(),
                    y = br.ReadSingle(),
                    z = br.ReadSingle(),
                };
                br.BaseStream.Position += 20;

                return node;
            }

            #endregion Public Methods
        }

        #endregion Private Structs
    }
}